<#assign object = doc.object>
package ${object.package}.gwt.client.model;

import java.util.HashMap;

import com.google.gwt.core.client.GWT;
import com.google.gwt.http.client.URL;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.data.RestDataSource;
import com.smartgwt.client.data.OperationBinding;
import com.smartgwt.client.data.fields.*;
import com.smartgwt.client.types.DSDataFormat;
import com.smartgwt.client.types.DSOperationType;
import com.smartgwt.client.types.DSProtocol;
<#if object.attributes.*.@regexp[0]??>
import com.smartgwt.client.widgets.form.validator.RegExpValidator;
</#if>

import ${object.package}.model.fields.*;
import ${object.package}.gwt.client.constants.Constants;

public class ${object.name}DataSource extends RestDataSource {

	private static final String JSON_URL = GWT.getModuleBaseURL()
			+ "${object.name?uncap_first}Operations.do";
	
	Constants constants = GWT.create(Constants.class);

	public ${object.name}DataSource(String id) {
		super();
		this.setID(id);
		// add id field
		DataSourceTextField idDataField = new DataSourceTextField(${object.name}Fields.id.name());
		//idDataField.setHidden(true);
		idDataField.setCanEdit(false);
		idDataField.setPrimaryKey(true);
		this.addField(idDataField);	
		<#list object.attributes?children as att>
		<#if att?node_name != "set" && att?node_name != "object" && att?node_type == "element">
			<#if att?node_name == "enum">
		DataSourceEnumField ${att.@class?uncap_first}DataField = new DataSourceEnumField(
				${object.name}Fields.${att.@class?uncap_first}.name(), constants.${object.name?uncap_first}_${att.@class}_table());
		HashMap<String, String> ${att.@class?uncap_first}Map = new HashMap<String, String>();
				<#list att.element as value>
		${att.@class?uncap_first}Map.put("${value.@name}","${value.@name}");
				</#list>
		${att.@class?uncap_first}DataField.setValueMap(${att.@class?uncap_first}Map);
			<#elseif att?node_name == "date">
		DataSourceDateField ${att.@name}DataField = new DataSourceDateField(
				${object.name}Fields.${att.@name}.name(), constants.${object.name?uncap_first}_${att.@name}_table());
			<#elseif att?node_name == "integer">
		DataSourceIntegerField ${att.@name}DataField = new DataSourceIntegerField(
				${object.name}Fields.${att.@name}.name(), constants.${object.name?uncap_first}_${att.@name}_table());
			<#elseif att?node_name == "boolean">
		DataSourceBooleanField ${att.@name}DataField = new DataSourceBooleanField(
				${object.name}Fields.${att.@name}.name(), constants.${object.name?uncap_first}_${att.@name}_table());
			<#elseif att?node_name == "string">
		DataSourceTextField ${att.@name}DataField = new DataSourceTextField(
				${object.name}Fields.${att.@name}.name(), constants.${object.name?uncap_first}_${att.@name}_table());
				<#if att.@maxlength[0]??>
		${att.@name}DataField.setLength(${att.@maxlength});
				</#if>
			<#else>
		DataSourceTextField ${att.@name}DataField = new DataSourceTextField(
				${object.name}Fields.${att.@name}.name(), constants.${object.name?uncap_first}_${att.@name}_table());
			</#if>
			<#if att.@notnull[0]??>
				<#if att.@notnull[0] == "true">
		${att.@name[0]!att.@class?uncap_first}DataField.setRequired(true);
				</#if>
			</#if>
			<#if att.@regexp[0]??>
		RegExpValidator ${att.@name}RegExpValidator = new RegExpValidator();
		${att.@name}RegExpValidator.setExpression("${att.@regexp}");
		${att.@name}DataField.setValidators(${att.@name}RegExpValidator);
			</#if>
		this.addField(${att.@name[0]!att.@class?uncap_first}DataField);	
		</#if>
		</#list>
		DataSourceTextField creationDateDataField = new DataSourceTextField("creationDate");
		creationDateDataField.setCanEdit(false);
		this.addField(creationDateDataField);
		DataSourceTextField updateDateDataField = new DataSourceTextField("updateDate");
		updateDateDataField.setCanEdit(false);
		this.addField(updateDateDataField);
		this.setDataFormat(DSDataFormat.JSON);
		this.setDataURL(URL.encode(JSON_URL));
		
		OperationBinding fetch = new OperationBinding(DSOperationType.FETCH,JSON_URL);
		fetch.setDataProtocol(DSProtocol.GETPARAMS);

		OperationBinding add = new OperationBinding(DSOperationType.ADD,JSON_URL);
		add.setDataProtocol(DSProtocol.GETPARAMS);

		OperationBinding update = new OperationBinding(DSOperationType.UPDATE,JSON_URL);
		update.setDataProtocol(DSProtocol.GETPARAMS);

		OperationBinding remove = new OperationBinding(DSOperationType.REMOVE,JSON_URL);
		remove.setDataProtocol(DSProtocol.GETPARAMS);

		setOperationBindings(fetch, update, remove, add);
		
	}

	private static ${object.name}DataSource instance = null;

	public static ${object.name}DataSource getInstance() {
		if (instance == null) {
			instance = new ${object.name}DataSource("${object.name}");
		}
		return instance;
	}

	@Override
	protected Object transformRequest(DSRequest request) {
		if (request.getOperationType().equals(DSOperationType.FETCH)) {
			if (request.getCriteria() != null
					&& request.getCriteria().getAttributes().length > 0) {
				HashMap params = new HashMap();
				params.put("findByParams", true);
				request.setParams(params);
			}
		}
		return super.transformRequest(request);
	}
	
	@Override
	protected void transformResponse(DSResponse response, DSRequest request,
			Object data) {
		super.transformResponse(response,request,data);
	}
}
